package com.ruoyi.cs.service.impl;

import java.awt.*;
import java.beans.Encoder;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.enums.WeaponType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.pay.HttpsUtils;
import com.ruoyi.common.yyyoupin.RSAUtils;
import com.ruoyi.common.yyyoupin.bean.CSGOKnife;
import com.ruoyi.common.yyyoupin.bean.SaleResponse;
import com.ruoyi.common.yyyoupin.bean.SaleResponseVo;
import com.ruoyi.cs.domain.TGoodsPool;
import com.ruoyi.cs.domain.ZBTGoodsPoolVo;
import com.ruoyi.cs.mapper.TBoxMapper;
import com.ruoyi.cs.mapper.TGoodsMapper;
import com.ruoyi.cs.mapper.TGoodsPoolMapper;
import com.ruoyi.cs.service.CommonService;
import com.ruoyi.cs.service.ITGoodsPoolService;
import com.ruoyi.cs.service.ITGoodsService;
import org.apache.poi.ss.formula.functions.T;
import org.apache.xmlbeans.impl.xb.xsdschema.BlockSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.activation.MailcapCommandMap;
import javax.net.ssl.HttpsURLConnection;
import javax.sound.sampled.AudioFormat;

/**
 * 饰品池信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-05-25
 */
@Service
@SuppressWarnings("all")
public class TGoodsPoolServiceImpl implements ITGoodsPoolService
{
    @Value("${ruoyi.yyfile}")
    private String yyfile;

    private static final Logger log = LoggerFactory.getLogger(TGoodsPoolServiceImpl.class);
    @Autowired
    private TGoodsPoolMapper tGoodsPoolMapper;
    @Autowired
    private CommonService commonService;
    @Autowired
    private TGoodsMapper tGoodsMapper;
    @Autowired
    private TBoxMapper tBoxMapper;
    @Autowired
    private ITGoodsService itGoodsService;

    /**
     * 查询饰品池信息
     * 
     * @param goodsId 饰品池信息ID
     * @return 饰品池信息
     */
    @Override
    public TGoodsPool selectTGoodsPoolById(String goodsId)
    {
        return tGoodsPoolMapper.selectTGoodsPoolById(goodsId);
    }

    /**
     * 查询饰品池信息列表
     * 
     * @param tGoodsPool 饰品池信息
     * @return 饰品池信息
     */
    @Override
    public List<TGoodsPool> selectTGoodsPoolList(TGoodsPool tGoodsPool)
    {
        return tGoodsPoolMapper.selectTGoodsPoolList(tGoodsPool);
    }

    /**
     * 新增饰品池信息
     * 
     * @param tGoodsPool 饰品池信息
     * @return 结果
     */
    @Override
    public int insertTGoodsPool(TGoodsPool tGoodsPool)
    {
        tGoodsPool.setCreateTime(DateUtils.getNowDate());
        tGoodsPool.setPrice(tGoodsPool.getGoodsPrice());
        tGoodsPool.setGoodsExprice(tGoodsPool.getGoodsPrice());
        return tGoodsPoolMapper.insertTGoodsPool(tGoodsPool);
    }

    /**
     * 修改饰品池信息
     * 
     * @param tGoodsPool 饰品池信息
     * @return 结果
     */
    @Override
    public int updateTGoodsPool(TGoodsPool tGoodsPool)
    {
        tGoodsPool.setUpdateTime(DateUtils.getNowDate());
        tGoodsPool.setGoodsExprice(tGoodsPool.getGoodsPrice());
        return tGoodsPoolMapper.updateTGoodsPool(tGoodsPool);
    }

    /**
     * 批量删除饰品池信息
     * 
     * @param goodsIds 需要删除的饰品池信息ID
     * @return 结果
     */
    @Override
    public int deleteTGoodsPoolByIds(String[] goodsIds)
    {
        return tGoodsPoolMapper.deleteTGoodsPoolByIds(goodsIds);
    }

    /**
     * 删除饰品池信息信息
     * 
     * @param goodsId 饰品池信息ID
     * @return 结果
     */
    @Override
    public int deleteTGoodsPoolById(String goodsId)
    {
        return tGoodsPoolMapper.deleteTGoodsPoolById(goodsId);
    }

    @Override
    public List<Map> goodsPoolInfoList(String goodsName) {
        return tGoodsPoolMapper.goodsPoolInfoList(goodsName);
    }

    @Override
    public Response<String> updateGoodsPool(String keyword){
        StringBuilder sb = new StringBuilder();
        sb.append("appId=");
        sb.append(Constants.APPID);
        sb.append("&app-key=");
        sb.append(Constants.APP_KEY);
        if(StringUtils.isNotEmpty(keyword)){
            sb.append("&keyword=");
            sb.append(toUtf8String(keyword));
        }
        sb.append("&page=");
        sb.append(1);
        sb.append("&limit=100");
        sb.append("&language=zh_CN");
        String  result = HttpsUtils.sendGet("https://app.zbt.com/open/product/v2/search",sb.toString(),null);
        JSONObject jsonObject = JSON.parseObject(result);
        if (jsonObject == null || !jsonObject.getBoolean("success")) {
            return Response.fail(Constants.FAILCODE,"获取饰品接口请求失败！");
        }
        JSONObject dataObject = jsonObject.getJSONObject("data");
        Integer total = dataObject.getInteger("total");
        Integer pages = dataObject.getInteger("pages");
        Integer page = dataObject.getInteger("page");
        Integer limit = dataObject.getInteger("limit");
        int count=0;
        for (int i=1;i<=pages;i++){
            boolean flag = this.batctAddGoodsPool(i,keyword);
            if (flag) {
                count++;
            }
        }
        String info = "调取饰品接口总次数为:"+pages+"次，成功插入数据库："+count+"次";
        log.info("调取饰品接口总次数为:{}次，成功插入数据库：{}次",pages,count);
        return Response.success(info);
    }

    public void batchUpdateGoodsPoolPrice( List<String> marketHashNameList){
        Map map = new HashMap();
        map.put("appId",Constants.APPID);
        map.put("marketHashNameList", marketHashNameList);
        String result = null;
        try {
            result =  HttpsUtils.sendPost("https://app.zbt.com/open/product/price/info?app-key="+Constants.APP_KEY+"&language=zh_CN", JSON.toJSONString(map),null );
        }catch (Exception e){
            log.error(e.getMessage());
        }
        log.info(result);
        if (result != null) {
            JSONObject jsonObject = JSON.parseObject(result);
            List<ZBTGoodsPoolVo> zbtGoodsPoolVos = JSONArray.parseArray(jsonObject.getString("data"),ZBTGoodsPoolVo.class);
            if (zbtGoodsPoolVos != null) {
                tGoodsPoolMapper.updateTGoodPsoolPrice(zbtGoodsPoolVos);
            }
        }
    }


    public Boolean batctAddGoodsPool(int page1,String keyword){
            StringBuilder sb = new StringBuilder();
            sb.append("appId=");
            sb.append(Constants.APPID);
            sb.append("&app-key=");
            sb.append(Constants.APP_KEY);
            if(StringUtils.isNotEmpty(keyword)){
                sb.append("&keyword=");
                sb.append(toUtf8String(keyword));
            }
            sb.append("&page=");
            sb.append(page1);
            sb.append("&limit=100");
            sb.append("&language=zh_CN");
            String  result = HttpsUtils.sendGet("https://app.zbt.com/open/product/v2/search",sb.toString(),null);
            log.info("获取ZBT饰品列表:{}",result);
            JSONObject jsonObject = JSON.parseObject(result);
            if (jsonObject == null || !jsonObject.getBoolean("success")) {
                return false;
            }
            JSONObject dataObject = jsonObject.getJSONObject("data");
            Integer total = dataObject.getInteger("total");
            Integer pages = dataObject.getInteger("pages");
            Integer page = dataObject.getInteger("page");
            Integer limit = dataObject.getInteger("limit");

            List<ZBTGoodsPoolVo> goodsPoolVoList = JSON.parseArray(dataObject.getString("list"), ZBTGoodsPoolVo.class);
            if (goodsPoolVoList == null || goodsPoolVoList.size()==0) {
                return false;
            }
            List<TGoodsPool> list = new ArrayList<>();
           try {
            for (ZBTGoodsPoolVo vo : goodsPoolVoList) {
                /**过滤掉无价格的饰品*/
                if(vo.getPriceInfo() == null){
                    continue;
                }
                TGoodsPool tg = new TGoodsPool();
                tg.setZBT(Integer.parseInt(vo.getItemId()));
                tg.setGoodsName(vo.getItemName());
                tg.setGoodsPic(vo.getImageUrl().contains("?") ? vo.getImageUrl().substring(0,vo.getImageUrl().indexOf("?")) : vo.getImageUrl());
                tg.setGoodsPrice(vo.getPriceInfo().getPrice() == null ? new BigDecimal(0) : new BigDecimal(vo.getPriceInfo().getPrice()));
                tg.setGoodsExprice(vo.getPriceInfo().getPrice() == null ? new BigDecimal(0) : new BigDecimal(vo.getPriceInfo().getPrice()));
                tg.setPrice(vo.getPriceInfo().getPrice() == null ? new BigDecimal(0) : new BigDecimal(vo.getPriceInfo().getPrice()));
                tg.setGoodsChance(new BigDecimal(0.01));
                tg.setGoodsStocknum(Long.parseLong(vo.getPriceInfo().getQuantity()));
                tg.setGoodsPutnum(Long.parseLong(vo.getPriceInfo().getQuantity()));
                tg.setGoodsGrate("0");
                tg.setGoodsWear(vo.getExterior());
                tg.setGoodsQuality(vo.getRarity());
                tg.setGoodsType("0");
                tg.setGoodsChance(new BigDecimal(0.01));
                tg.setMarketHashName(vo.getMarketHashName());
                String type = vo.getType();
                if ("csgo_type_knife".equalsIgnoreCase(type)) {
                    tg.setGoodsMold("0");
                }else if ("csgo_type_pistol".equalsIgnoreCase(type)) {
                    tg.setGoodsMold("1");
                }else if ("csgo_type_rifle".equalsIgnoreCase(type)) {
                    tg.setGoodsMold("2");
                }else if ("csgo_type_smg".equalsIgnoreCase(type)) {
                    tg.setGoodsMold("3");
                }else if ("type_hands".equalsIgnoreCase(type)) {
                    tg.setGoodsMold("4");
                }else if ("csgo_type_machinegun".equalsIgnoreCase(type)) {
                    tg.setGoodsMold("6");
                }else if (vo.getItemName().contains("SSG 08") || vo.getItemName().contains("AWP") ||  vo.getItemName().contains("G3SG1")){
                    tg.setGoodsMold("5");
                }else if (vo.getItemName().contains("SCAR-20")){
                    tg.setGoodsMold("2");
                }else  if (vo.getItemName().contains("新星") || vo.getItemName().contains("MAG-7") || vo.getItemName().contains("XM1014") || vo.getItemName().contains("截短霰弹枪")) {
                    tg.setGoodsMold("6");
                }
                else {
                    tg.setGoodsMold("7");
                }
                tg.setCreateTime(DateUtils.getNowDate());
                tg.setUpdateTime(DateUtils.getNowDate());

                /**添加人工和自动发货信息*/
                tg.setAutoDeliverPrice(vo.getPriceInfo().getAutoDeliverPrice() == null ? new BigDecimal(0) : new BigDecimal(vo.getPriceInfo().getAutoDeliverPrice()));
                tg.setAutoDeliverQuantity(Long.parseLong(vo.getPriceInfo().getAutoDeliverQuantity()));
                tg.setManualDeliverPrice(vo.getPriceInfo().getManualDeliverPrice() == null ? new BigDecimal(0) : new BigDecimal(vo.getPriceInfo().getManualDeliverPrice()));
                tg.setManualQuantity(Long.parseLong(vo.getPriceInfo().getManualQuantity()));
                list.add(tg);
            }
            tGoodsPoolMapper.insertTGoodsPoolBatch(list);
            return true;
        }catch (Exception e){
             log.error("获取饰品数据插入数据库异常：{}",e.getMessage());
             log.error("集合：{}",JSON.toJSONString(list));
              e.printStackTrace();
            return false;
        }

    }

    public  String toUtf8String(String string) {
        StringBuilder stringBuffer = new StringBuilder();
        for (int i = 0; i < string.length(); i++) {
            char c = string.charAt(i);
            if (c <= 255 && c != '|' && c != ' ') {
                stringBuffer.append(c);
            } else {
                byte[] b;
                try {
                    b = Character.toString(c).getBytes(StandardCharsets.UTF_8);
                } catch (Exception ex) {
                    b = new byte[0];
                }
                for (int value : b) {
                    int k = value;
                    if (k < 0) k += 256;
                    stringBuffer.append("%").append(Integer.toHexString(k).toUpperCase());
                }
            }
        }
        return stringBuffer.toString();
    }

    @Override
    public Response<String> updateGoodsPoolYY(String keyword){
        try {
            /**查询模板ID获取*/
            String url = "https://gw-openapi.youpin898.com/open/v1/api/templateQuery";
            Map<String, Object> params = RSAUtils.toParams();
            params.put("sign",RSAUtils.getSign(params));
            String fileData =  RSAUtils.toPost(url,params);
            JSONObject jsonObject = JSON.parseObject(fileData);
            if(jsonObject.getInteger("code") != 0){
                return Response.fail("获取查询模板ID失败:"+jsonObject.getString("msg"));
            }
            String fileUrl = jsonObject.getString("data");

            /**下载文件并解析*/
            // 获取文件名
            String fileName = FileUtil.getName(fileUrl);
            // 设置文件保存路径

            String savePath = yyfile+UUID.randomUUID()+".txt";
            // 下载文件
            HttpUtil.downloadFile(fileUrl, savePath);

            List<CSGOKnife> items = readItemsFromFile(savePath);
            if(StringUtils.isNotEmpty(keyword)){
                items = items.stream().filter(bean -> bean.getName().contains(keyword)).collect(Collectors.toList());
            }
            if(CollectionUtil.isEmpty(items)){
                return Response.success("无数据添加");
            }
            int batchSize = 100;
            int totalItems = items.size();
            for (int i = 0; i < totalItems; i += batchSize) {
                int endIndex = Math.min(i + batchSize, totalItems);
                List<CSGOKnife> batch = items.subList(i, endIndex);
                // 将当前批次的数据保存到数据库中的操作
                saveBatchToDatabase(batch);
            }
            log.info("更新商品条数:{}",totalItems);
            return Response.success("更新成功");
        } catch (IOException e) {
            e.printStackTrace();
            return Response.success("更新异常:{}",e.getMessage());
        }
    }

    private  void saveBatchToDatabase(List<CSGOKnife> knifeList) {
        List<TGoodsPool> tGoodsPools = new ArrayList<>();
        knifeList.forEach(csgo -> {
            TGoodsPool tGoodsPool = new TGoodsPool();
            tGoodsPool.setGoodsName(csgo.getName());
            tGoodsPool.setMarketHashName(csgo.getHashName());
            tGoodsPool.setGoodsMold(WeaponType.getTypeName(csgo.getTypeName()).getCode());
            tGoodsPool.setZBT(csgo.getId());
            tGoodsPool.setGoodsPrice(BigDecimal.ZERO);
            tGoodsPool.setGoodsExprice(BigDecimal.ZERO);
            tGoodsPool.setGoodsChance(new BigDecimal("0.01"));
            tGoodsPool.setGoodsStocknum(999L);
            tGoodsPool.setGoodsPutnum(999L);
            tGoodsPool.setGoodsType("0");
            tGoodsPool.setGoodsGrate("0");
            tGoodsPool.setCreateTime(DateUtils.getNowDate());
            tGoodsPools.add(tGoodsPool);
        });
        tGoodsPoolMapper.insertTGoodsPoolBatchYY(tGoodsPools);
    }


    private static List<CSGOKnife> readItemsFromFile(String filePath) throws IOException {
        StringBuilder content = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                content.append(line);
            }
        }

        Gson gson = new Gson();
        Type itemType = new TypeToken<List<CSGOKnife>>() {}.getType();
        return gson.fromJson(content.toString(), itemType);
    }

    @Override
    public Response updateGoodsPoolPrice() {
        List<Integer> list = tGoodsPoolMapper.getAlltemplateIds();
        int chunkSize = 200;
        List<List<Integer>> listGroup = partitionList(list, chunkSize);
        if (!listGroup.isEmpty()) {
            ExecutorService executor = Executors.newFixedThreadPool(5);
            try {
                List<CompletableFuture<Void>> futures = listGroup.stream()
                        .map(sublist -> CompletableFuture.runAsync(() -> batchUpdateGoodsPoolPriceYY(sublist), executor))
                        .collect(Collectors.toList());
                CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
                allFutures.get();
                /**自动更新饰品价格*/
                completeUpdateGoodsPrice();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                executor.shutdown();
            }
        }
        return Response.success();
    }
    private List<List<Integer>> partitionList(List<Integer> list, int pageSize) {
        List<List<Integer>> listGroup = new ArrayList<>();
        int listSize = list.size();
        for (int i = 0; i < listSize; i += pageSize) {
            if (i + pageSize > listSize) {
                pageSize = listSize - i;
            }
            List<Integer> newList = list.subList(i, i + pageSize);
            listGroup.add(newList);
        }
        return listGroup;
    }

    /**悠悠有品交易饰品更新价格*/
    public void batchUpdateGoodsPoolPriceYY( List<Integer> templateHashIds){
//        log.info("批量更新价格个数:{},内容:{}",templateHashIds.size(),JSON.toJSONString(templateHashIds));
        List<SaleResponse> list = commonService.priceInfoYY(templateHashIds);
        if(CollectionUtil.isNotEmpty(list)){
            List<SaleResponseVo> saleResponseVoList = commonService.toSaleResponseVo(list);
            tGoodsPoolMapper.updateTGoodPsoolPriceYY(saleResponseVoList);
        }
        log.info("批量更新价格完成个数:{}",list.size());
    }

    @Override
    @Async(value = "threadPoolTaskExecutor")
    public Response completeUpdateGoodsPrice() {

        /**更新箱子饰品以及箱子价格*/
        CompletableFuture<Void> updateBoxInfoFuture = CompletableFuture.runAsync(() -> itGoodsService.updateBoxInfo());

        /**更新饰品商城和幸运饰品价格*/
        CompletableFuture<Void> updateMaxAndLuckGoodsPriceFuture = CompletableFuture.runAsync(() -> tGoodsMapper.updateMaxAndLuckGoodsPrice());

        /**更新未上限的roll房饰品价格*/
        CompletableFuture<Void> updateRollGoodsPriceFuture = CompletableFuture.runAsync(() -> tGoodsMapper.updateRollGoodsPrice());

        CompletableFuture<Void> allOf = CompletableFuture.allOf(updateBoxInfoFuture, updateMaxAndLuckGoodsPriceFuture, updateRollGoodsPriceFuture);
        return allOf.thenApply((result) -> {
            // 所有任务完成后的处理
            return Response.success();
        }).join();
    }
}
